`include "PRV564Config.v"
`include "PRV564Define.v"

//----------------------------------------------------------
//AXI_axcache 全部置零  未启用AXI总线中的buffer和cache功能
//AXI_axprot  全部置零	未启用访问权限功能
//AXI_axqos	  全部置零  未启用传输优先级功能
//AXI_axregion全部置零  未启用访存区域选择功能
//AXI_axuser  用户定义的信号暂不使用
//
//回复信号的优先级 Decode_ERROR > SFR > B > RD
//
//-------------------------------------------------------------


module FIB2AXI_old #(
	parameter AXI_ID_WIDTH 	= 8
)
(
    input  wire             		CLKi,
    input  wire             		RSTi,
//--------------------FIB interface----------------
    output  reg             		FIBo_ACK,         //ack for valid (read a new access from FIFO)
    input  wire             		FIBi_V,           //request acknowledge
    input  wire [7:0]       		FIBi_ID,
    input  wire [7:0]       		FIBi_CMD,
    input  wire [3:0]       		FIBi_BURST,
    input  wire [3:0]       		FIBi_SIZE,
    input  wire [`XLEN-1:0] 		FIBi_ADDR,      
    input  wire [`XLEN-1:0] 		FIBi_DATA,
    //            reply to master
    output  reg [7:0]       		FIBo_ID,
    output  reg [7:0]       		FIBo_RPL,			//应答
    output  reg             		FIBo_WREN,
    input  wire             		FIBi_FULL,         //result FIFO is FULL, can not write
//  output  reg             		FIBo_ADDR,
    output  reg [`XLEN-1:0] 		FIBo_DATA,
//------------------SFR interface------------------------
    //        SFR : Special Function Register, 是核心私有的寄存器
    // SFR operation Timing:
    //                 |<-Read operation ->|<-Write Operation->|<-No operation
    //  CLK       :____/----\____/----\____/----\____/----\____/----\____/----\
    //  SFRi_ADDR :----<      ADDR0       ><       ADDR1       >---------------
    //  SFRi_DATA :------------------------<       DATA1       >---------------
    //  SFRi_CS   :____/---------------------------------------\_______________
    //  SFRi_WR   :________________________/-------------------\_______________
    //  SFRo_DATA :--------------<  DATA0  >-----------------------------------
	// 缺少数据流速控制的信号，如果读数据集中反馈，CPU处理不及时，而FIFO深度不够时，SFR读回数据将丢失
    output  reg [`XLEN-1:0] 		FIBo_SFRi_ADDR,
    output  reg [`XLEN-1:0] 		FIBo_SFRi_DATA,
    output  reg             		FIBo_SFRi_CS,            //SFR select
    output  reg             		FIBo_SFRi_WR,            //write to SFR
    input  wire [`XLEN-1:0] 		FIBi_SFRo_DATA,
//-------------------AXI interface---------------------
//-------------------写地址通道-----------------------
    output reg [AXI_ID_WIDTH-1:0]  	FIBo_AXI_awid,
    output reg [`XLEN-1:0]    		FIBo_AXI_awaddr,
    output reg [7:0]               	FIBo_AXI_awlen,
    output reg [2:0]               	FIBo_AXI_awsize,
    output reg [1:0]               	FIBo_AXI_awburst,
    //output reg                     	FIBo_AXI_awlock,
    // output reg [3:0]               	FIBo_AXI_awcache,
    // output reg [2:0]               	FIBo_AXI_awprot,
    // output reg [3:0]               	FIBo_AXI_awqos,
    // output reg [3:0]               	FIBo_AXI_awregion,
//  output reg [AWUSER_WIDTH-1:0]  	FIBo_AXI_awuser,
    output reg                     	FIBo_AXI_awvalid,
    input  wire                     FIBi_AXI_awready,
//---------------------写数据通道-----------------------------
    output reg [`XLEN-1:0]  		FIBo_AXI_wdata,
    output reg [7:0]  				FIBo_AXI_wstrb,
    output reg                     	FIBo_AXI_wlast,
//  output reg [WUSER_WIDTH-1:0]   	FIBo_AXI_wuser,
    output reg                     	FIBo_AXI_wvalid,
    input  wire                     FIBi_AXI_wready,
//----------------------写回复通道-------------------------------	
    input  wire [AXI_ID_WIDTH-1:0]  FIBi_AXI_bid,
    input  wire [1:0]               FIBi_AXI_bresp,
//  input  wire [BUSER_WIDTH-1:0]   FIBi_AXI_buser,
    input  wire                     FIBi_AXI_bvalid,
    output reg                     	FIBo_AXI_bready,
//---------------------读地址通道-----------------------------------	
    output reg [AXI_ID_WIDTH-1:0]   FIBo_AXI_arid,
    output reg [`XLEN-1:0]    		FIBo_AXI_araddr,
    output reg [7:0]               	FIBo_AXI_arlen,
    output reg [2:0]               	FIBo_AXI_arsize,
    output reg [1:0]               	FIBo_AXI_arburst,
    //output reg                     	FIBo_AXI_arlock,
    // output reg [3:0]               	FIBo_AXI_arcache,
    // output reg [2:0]               	FIBo_AXI_arprot,
    // output reg [3:0]               	FIBo_AXI_arqos,
    // output reg [3:0]               	FIBo_AXI_arregion,
//  output reg [ARUSER_WIDTH-1:0]  	FIBo_AXI_aruser,
    output reg                     	FIBo_AXI_arvalid,
    input  wire                     FIBi_AXI_arready,
//----------------------读数据通道----------------------------------
    input  wire [AXI_ID_WIDTH-1:0]  FIBi_AXI_rid,
    input  wire [`XLEN-1:0]  		FIBi_AXI_rdata,
    input  wire [1:0]               FIBi_AXI_rresp,
    input  wire                     FIBi_AXI_rlast,
//  input  wire [RUSER_WIDTH-1:0]   FIBi_AXI_ruser,
    input  wire                     FIBi_AXI_rvalid,
    output reg                     	FIBo_AXI_rready
);


//FIB指令译码
	wire op_NOOP;					//无操作
	wire op_SIGR;					//单次读操作
	wire op_SIGW;					//单次写操作
	wire op_SEQR;					//连续读操作
	wire op_SEQW;					//连续写操作
	wire op_WAPR;					//回卷读操作
	wire op_WAPW;					//回卷写操作
	wire op_AMOR;					//原子读操作
	wire op_AMOW;					//原子写操作
	wire op_SEQE;					//连续传输结束操作
	wire op_DEC_ERR;				//译码出错
	
	wire SFR_access;				//访问SFR选通信号信号
	wire AXI_RA_access;				//访问AXI读地址通道选通信号
	wire AXI_WA_access;				//访问AXI写地址通道选通信号
	wire AXI_WD_access;				//访问AXI写数据通道选通信号

//CMD格式转换
	reg [7:0] FIBo_AXI_axlen_tem;
	wire [1:0] FIBo_AXI_axburst_tem;
	wire FIBo_AXI_axlock_tem;
	reg [7:0] AXI_WSTRB;			//字节掩码
	
	reg SFR_ACK;					//访问SFR反馈的应答信号
	reg AXI_WAACK;					//AXI写地址应答信号
	reg AXI_WDACK;					//AXI写数据应答信号
	reg AXI_RAACK;					//AXI读地址应答信号
	
	wire [7:0] SFR_RPL;				//SFR反馈的传输状态信号
	reg [7:0] AXI_BRPL;				//AXI反馈的传输状态信号
	reg [7:0] AXI_RRPL;				//AXI反馈的传输状态信号
	
	wire [AXI_ID_WIDTH-1:0] AXI_BID;
	wire [AXI_ID_WIDTH-1:0] SFR_BID;
	wire [AXI_ID_WIDTH-1:0] AXI_RID;
	
	reg SFR_busying;				//SFR正在读写数据标志信号，防止一次读写SFR数据后的下一个clock进行SFR读写
	reg SFR_RD_valid;				//读回数据有效信号
	wire [`XLEN-1:0] SFR_RD_data; 	//SFR读回的数据
	wire [`XLEN-1:0] AXI_RD_data; 	//AXI读回的数据

//--------------------------------------------------------------------------------------------
//----------------------------------FIB指令译码-----------------------------------------------
//
assign op_NOOP = (FIBi_CMD == 8'h00) ? 1'b1 : 1'b0;
assign op_SIGR = (FIBi_CMD == 8'h01) ? 1'b1 : 1'b0;
assign op_SIGW = (FIBi_CMD == 8'h02) ? 1'b1 : 1'b0;
assign op_SEQR = (FIBi_CMD == 8'h03) ? 1'b1 : 1'b0;
assign op_SEQW = (FIBi_CMD == 8'h04) ? 1'b1 : 1'b0;
assign op_WAPR = (FIBi_CMD == 8'h05) ? 1'b1 : 1'b0;
assign op_WAPW = (FIBi_CMD == 8'h06) ? 1'b1 : 1'b0;
assign op_AMOR = (FIBi_CMD == 8'h07) ? 1'b1 : 1'b0;
assign op_AMOW = (FIBi_CMD == 8'h08) ? 1'b1 : 1'b0;
assign op_SEQE = (FIBi_CMD == 8'h14) ? 1'b1 : 1'b0;
assign op_DEC_ERR = (!(op_NOOP|op_SIGR|op_SIGW|op_SEQR|op_SEQW|op_WAPR|op_WAPW|op_AMOR|op_AMOW|op_SEQE) | (SFR_access &!(op_SIGR|op_SIGW))) ? 1'b1 : 1'b0; //解码出错

//译码出错
	reg DEC_ERR_flag;
	reg [7:0] DEC_ERR_ID;
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		DEC_ERR_flag 	<= 'd0;
		DEC_ERR_ID  	<= 'd0;
		end
	else if(op_DEC_ERR) begin
		DEC_ERR_flag 	<= 1'b1;
		DEC_ERR_ID 		<= FIBi_ID;
		end
	else if(DEC_ERR_flag & (!FIBi_FULL | (FIBi_FULL & !FIBo_WREN))) begin
		DEC_ERR_flag 	<= 1'b0;
		DEC_ERR_ID 		<= 'd0;
		end
	else begin
		DEC_ERR_flag 	<= DEC_ERR_flag;
		DEC_ERR_ID 		<= DEC_ERR_ID;
		end
	end
	

//----------------------------------------------------------------------------------------------
//------------------------------------地址路由--------------------------------------------------
//
//FIB工作状态  便于CMD = SEQE 时数据的路由
	reg [2:0] FIB_state;
	parameter IDLE 		= 3'd0;		//空闲
	parameter GENERAL 	= 3'd1;		//单词读写的常规读写状态
	parameter AMOR		= 3'd2;		//原子读操作状态
	parameter AMOW		= 3'd3;		//原子写操作状态
	parameter SEQW 		= 3'd4;		//连续写状态
	parameter SEQR 		= 3'd5;		//连续写状态	

always@(*) begin
	// if(RSTi) beginposedge CLKi or posedge RSTi
	// 	FIB_state <= IDLE;
	// 	end
	// else 
	if(op_SIGR|op_SIGW|op_WAPR|op_WAPW) begin
		FIB_state = GENERAL;
		end
	else if(op_SEQR) begin
		FIB_state = SEQR;
		end
	else if(op_SEQW) begin
		FIB_state = SEQW;
		end
	else if(op_AMOR) begin
		FIB_state = AMOR;
		end
	else if(op_AMOW) begin
		FIB_state = AMOW;
		end
	else begin
		FIB_state = IDLE;
		end
	end

//
//存在写地址通道和写数据通道Ready的状态不同的时候，为防止此时数据丢失，
//采取状态机来关闭以传输数据的通道（WA or WD），开启尚未传输完成的通道（WA or WD）
//
	reg [1:0] WA_WD_access_state;	//WA WD通道开启状态
	parameter WA_nWD	= 2'd0;			//WA通道开启 WD通道未开启
	parameter nWA_WD	= 2'd1;			//WA通道未开启 WD通道开启
	parameter WA_WD		= 2'd2;			//WA通道开启 WD通道开启
	parameter nWA_nWD	= 2'd3;			//WA通道未开启 WD通道未开启

always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		WA_WD_access_state <= 2'd3;
		end
	else if(FIBi_V & !SFR_access & !AXI_RA_access) begin
		case({(FIBo_AXI_awvalid&!FIBi_AXI_awready),(FIBo_AXI_wvalid&!FIBi_AXI_wready)})
			2'b00	: WA_WD_access_state <= WA_WD;
			2'b01	: WA_WD_access_state <= WA_nWD;
			2'b10	: WA_WD_access_state <= nWA_WD;
			2'b11	: WA_WD_access_state <= nWA_nWD;
			default	: WA_WD_access_state <= nWA_nWD;
		endcase
		end
	else begin
		case(WA_WD_access_state) 
			WA_nWD	:begin
					if(FIBi_AXI_wready) begin
						WA_WD_access_state <= nWA_nWD;
						end
					else begin
						WA_WD_access_state <= WA_WD_access_state;
						end
					end
			nWA_WD  :begin
					if(FIBi_AXI_awready) begin
						WA_WD_access_state <= nWA_nWD;
						end
					else begin
						WA_WD_access_state <= WA_WD_access_state;
						end
					end
			default	: begin 
						WA_WD_access_state <= nWA_nWD;
						end
		endcase
		end
	end

assign SFR_access 		= ((FIBi_ADDR & `SFR_ADDR_MASK) == `SFR_ADDR_SEG) ? 1'b1 : 1'b0;
assign AXI_RA_access 	= (!SFR_access & (op_SIGR | op_SEQR | op_WAPR | op_AMOR | (FIB_state == SEQR && op_SEQE))) ? 1'b1 : 1'b0;
assign AXI_WA_access	= (!SFR_access & (WA_WD_access_state == nWA_WD | WA_WD_access_state == nWA_nWD | WA_WD_access_state == WA_WD) & 	
							(op_SIGW | op_SEQW | op_WAPW | op_AMOW | (FIB_state == SEQW && op_SEQE) )) ? 1'b1 : 1'b0;
assign AXI_WD_access	= (!SFR_access & (WA_WD_access_state == WA_nWD | WA_WD_access_state == nWA_nWD | WA_WD_access_state == WA_WD) & 
							(op_SIGW | op_SEQW | op_WAPW | op_AMOW | (FIB_state == SEQW && op_SEQE))) ? 1'b1 : 1'b0;

//------------------------------------------------------------------------------------------------
//---------------------------------数据格式转换电路-----------------------------------------------
//
//突发长度转换电路 FIBi_BURST --> FIBo_AXI_axlen
always@(*) begin
	case(FIBi_BURST[3:0]) 
		4'd0 	: begin FIBo_AXI_axlen_tem = 8'b00000000; end
		4'd1 	: begin FIBo_AXI_axlen_tem = 8'b00000001; end
		4'd2 	: begin FIBo_AXI_axlen_tem = 8'b00000011; end
		4'd3 	: begin FIBo_AXI_axlen_tem = 8'b00000111; end
		4'd4 	: begin FIBo_AXI_axlen_tem = 8'b00001111; end
		4'd5 	: begin FIBo_AXI_axlen_tem = 8'b00011111; end
		4'd6 	: begin FIBo_AXI_axlen_tem = 8'b00111111; end
		4'd7 	: begin FIBo_AXI_axlen_tem = 8'b01111111; end
		4'd8 	: begin FIBo_AXI_axlen_tem = 8'b11111111; end
		default : begin FIBo_AXI_axlen_tem = 8'b00000000; end
	endcase
	end

//突发类型转换电路 
assign FIBo_AXI_axburst_tem = (op_WAPR | op_WAPW) ?  2'b10 : 1'b01;  //回卷读写 递增读写

//FIBo_AXI_axlock_tem 锁定总线信号生成
assign FIBo_AXI_axlock_tem = (op_AMOR) ? 1'b1 : 1'b0;

//AXI_WSTRB	写数据字节掩码
always@(*) begin
	case(FIBi_SIZE)
		4'd3	: begin
					case(FIBi_ADDR[2:0])
						3'd0	: begin AXI_WSTRB = 8'b00000001; end
						3'd1	: begin AXI_WSTRB = 8'b00000010; end
						3'd2	: begin AXI_WSTRB = 8'b00000100; end
						3'd3	: begin AXI_WSTRB = 8'b00001000; end
						3'd4	: begin AXI_WSTRB = 8'b00010000; end
						3'd5	: begin AXI_WSTRB = 8'b00100000; end
						3'd6	: begin AXI_WSTRB = 8'b01000000; end
						3'd7	: begin AXI_WSTRB = 8'b10000000; end
						default	: begin AXI_WSTRB = 8'b00000000; end
					endcase
					end
		4'd4	: begin 
					case(FIBi_ADDR[2:1]) 
						2'd0	: begin AXI_WSTRB = 8'b00000011; end
						2'd1	: begin AXI_WSTRB = 8'b00001100; end
						2'd2	: begin AXI_WSTRB = 8'b00110000; end
						2'd3	: begin AXI_WSTRB = 8'b11000000; end
						default	: begin AXI_WSTRB = 8'b00000000; end
					endcase
					end
		4'd5	: begin
					case(FIBi_ADDR[2])
						1'b0	: begin AXI_WSTRB = 8'b00001111; end
						1'b1	: begin AXI_WSTRB = 8'b11110000; end
						default	: begin AXI_WSTRB = 8'b00000000; end
					endcase
					end
		4'd6	: begin AXI_WSTRB = 8'b11111111; end
		default	: begin AXI_WSTRB = 8'b00000000; end
	endcase
	end	




//------------------------------------------------------------------------------
//--------------------------访存指令发出&回复计数器-----------------------------
/*reg [7:0] Send_reply_Int_cnt;
wire tran_end_flag;		//所有传输都已经得到回复标志信号
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		Send_reply_Int_cnt <= 'd0;
		end
	else if(FIBo_ACK & FIBi_V & !(FIBo_WREN & !FIBi_FULL)) begin
		Send_reply_Int_cnt <= Send_reply_Int_cnt + 1;
		end
	else if(!(FIBo_ACK & FIBi_V) & FIBo_WREN & !FIBi_FULL) begin
		Send_reply_Int_cnt <= Send_reply_Int_cnt - 1;
		end
	else begin
		Send_reply_Int_cnt <= Send_reply_Int_cnt;
		end
	end

assign 	tran_end_flag = (Send_reply_Int_cnt == 8'd0) ? 1'b1 : 1'b0;
*/


//-------------------------------------------------------------------------------
//---------------------------FIB interface--------------------------------------
//
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIBo_ID 		<= 'd0;
		FIBo_RPL 		<= 'd0;
		FIBo_WREN 		<= 'd0;
		FIBo_DATA    	<= 'd0;
		end
	else if(FIBo_WREN & FIBi_FULL) begin
		FIBo_ID 		<= {4'b0,FIBo_ID};
		FIBo_RPL 		<= FIBo_RPL;
		FIBo_WREN 		<= FIBo_WREN;
		FIBo_DATA    	<= FIBo_DATA;
		end
	else if(DEC_ERR_flag) begin				//译码出错
		FIBo_ID 		<= DEC_ERR_ID;
		FIBo_RPL 		<= 8'hf0;
		FIBo_WREN 		<= DEC_ERR_flag;
		FIBo_DATA    	<= 'd0;	
		end		
	else if(SFR_RD_valid) begin				//发送读SFR返回数据
		FIBo_ID 		<= SFR_BID;
		FIBo_RPL 		<= SFR_RPL;
		FIBo_WREN 		<= SFR_RD_valid;
		FIBo_DATA    	<= SFR_RD_data;	
		end
	else if(SFR_busying) begin
		FIBo_ID 		<= SFR_BID;
		FIBo_RPL 		<= SFR_RPL;
		FIBo_WREN 		<= 1'b1;
		FIBo_DATA    	<= 'd0;	
		end		
	else if(FIBi_AXI_bvalid) begin			//发送AXI写通道返回数据
		FIBo_ID 		<= AXI_BID;
		FIBo_RPL 		<= AXI_BRPL;
		FIBo_WREN 		<= FIBi_AXI_bvalid;
		FIBo_DATA    	<= 'd0;	
		end
	else if(FIBi_AXI_rvalid) begin			//发送AXI读通道返回数据
		FIBo_ID 		<= AXI_RID;
		FIBo_RPL 		<= AXI_RRPL;
		FIBo_WREN 		<= FIBi_AXI_rvalid;
		FIBo_DATA    	<= AXI_RD_data;	
		end	
	else begin					
		FIBo_ID 		<= 'd0;
		FIBo_RPL 		<= 'd0;
		FIBo_WREN 		<= 'd0;
		FIBo_DATA    	<= 'd0;
		end	
	end

//FIBo_ACK 
always@(*) begin
	if(FIBi_V) begin
		if(RSTi) begin 
			FIBo_ACK = SFR_ACK;
			end
		else if(SFR_access) begin
			FIBo_ACK = SFR_ACK;
			end
		else if(AXI_RA_access) begin
			FIBo_ACK = AXI_RAACK;
			end
		else if(AXI_WA_access & AXI_WD_access) begin 		//正常情况下（写地址和写数据通道同时可以写入）	
			if(AXI_WAACK & AXI_WDACK) begin
				FIBo_ACK = AXI_WAACK;
				end
			else begin
				FIBo_ACK = 1'b0;
				end
			end
		else if(AXI_WA_access & !AXI_WD_access ) begin	//写地址和写数据通道不可以同时写入
			FIBo_ACK = AXI_WAACK;
			end
		else if(!AXI_WA_access & AXI_WD_access ) begin	//写地址和写数据通道不可以同时写入
			FIBo_ACK = AXI_WDACK;
			end
		else begin
			FIBo_ACK = 1'b1;
			end
		end
	else begin
		FIBo_ACK = 1'b1;
		end
	end			

//-------------------------------------------------------------------------------------------
//------------------------------------SFR interface------------------------------------------
//
//SFR工作状态
//SFR_busying SFR繁忙标志位
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		SFR_busying <= 'd0;
		end
	else if(FIBo_SFRi_CS) begin 
		SFR_busying <= 1'b1;
		end
	else if(SFR_busying & (!FIBi_FULL | (FIBi_FULL & !FIBo_WREN))) begin
		SFR_busying <= 'd0;
		end
	else begin
		SFR_busying <= SFR_busying;
		end
	end

//SFR_RD_valid 读回数据有效标志位
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		SFR_RD_valid <= 1'b0;
		end
	else if(FIBo_SFRi_CS & !FIBo_SFRi_WR) begin
		SFR_RD_valid <= 1'b1;
		end
	else if(SFR_RD_valid & !DEC_ERR_flag)begin
		SFR_RD_valid <= 1'b0;
		end
	else begin
		SFR_RD_valid <= SFR_RD_valid;
		end
	end

//FIBo_SFRi_ADDR
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIBo_SFRi_ADDR <= 'd0;
		end
	else if(SFR_access & FIBi_V & (op_SIGR | op_SIGW) & !SFR_busying) begin 	// 地址路由 FIB输入地址有效
		FIBo_SFRi_ADDR <= FIBi_ADDR;
		end
	else begin
		FIBo_SFRi_ADDR <= FIBo_SFRi_ADDR;
		end
	end

//FIBo_SFRi_DATA
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIBo_SFRi_DATA <= 'd0;
		end
	else if(SFR_access & FIBi_V & op_SIGW & !SFR_busying) begin	// 地址路由 FIB输入地址有效 写操作
		FIBo_SFRi_DATA <= FIBi_DATA;
		end
	else begin
		FIBo_SFRi_DATA <= FIBo_SFRi_DATA;
		end
	end

//FIBo_SFRi_CS
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIBo_SFRi_CS <= 'd0;
		end
	else if(SFR_access & FIBi_V & (op_SIGR | op_SIGW) & !SFR_busying) begin
		FIBo_SFRi_CS <= 1'b1;
		end
	else begin
		FIBo_SFRi_CS <= 'd0;
		end
	end

//FIBo_SFRi_WR
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIBo_SFRi_WR <= 'd0;
		end
	else if(SFR_access & FIBi_V & op_SIGW & !SFR_busying) begin
		FIBo_SFRi_WR <= 1'b1;
		end
	else begin
		FIBo_SFRi_WR <= 'd0;
		end
	end

//SFR_ACK
always@(*) begin
	if(SFR_access & FIBi_V) begin
		if(RSTi) begin
			SFR_ACK = 1'b1;
			end
		else if(SFR_busying) begin
			SFR_ACK = 1'b0;
			end
		else begin
			SFR_ACK = 1'b1;
			end
		end
	else begin
		SFR_ACK = 1'b0;
		end
	end

//SFR_RD_data SFR读回的数据
assign SFR_RD_data = (SFR_RD_valid) ? FIBi_SFRo_DATA : {`XLEN{1'b0}};

//SFR_RPL
assign SFR_RPL = (SFR_busying) ? 8'h10 : 8'h00;

//SFR_BID
reg [AXI_ID_WIDTH-1:0] reg_SFR_BID;				//SFR反馈的ID寄存器
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		reg_SFR_BID <= 'd0;
		end
	else if(FIBo_SFRi_CS) begin
		reg_SFR_BID <= FIBi_ID;
		end
	else begin
		reg_SFR_BID <= reg_SFR_BID;
		end
	end
	
assign SFR_BID = (SFR_busying) ? reg_SFR_BID : 8'd0;


//---------------------------------------------------------------------------------
//------------------------------- AXI interface ----------------------------------- 
//
//-------------------写地址通道---------------------
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIBo_AXI_awid 		<= 'd0;
		FIBo_AXI_awaddr 	<= 'd0;
		FIBo_AXI_awlen 		<= 'd0;
		FIBo_AXI_awsize 	<= 'd0;
		FIBo_AXI_awburst 	<= 'd0;
		// FIBo_AXI_awlock 	<= 'd0;
		// FIBo_AXI_awcache 	<= 'd0;
		// FIBo_AXI_awprot 	<= 'd0;
		// FIBo_AXI_awqos 		<= 'd0;
		// FIBo_AXI_awregion 	<= 'd0;
		FIBo_AXI_awvalid 	<= 'd0;
		end
	else if(FIBo_AXI_awvalid & !FIBi_AXI_awready) begin
		FIBo_AXI_awid 		<= FIBo_AXI_awid;
		FIBo_AXI_awaddr 	<= FIBo_AXI_awaddr;
		FIBo_AXI_awlen 		<= FIBo_AXI_awlen;
		FIBo_AXI_awsize 	<= FIBo_AXI_awsize;
		FIBo_AXI_awburst 	<= FIBo_AXI_awburst;
		// FIBo_AXI_awlock		<= FIBo_AXI_awlock;
		// FIBo_AXI_awcache 	<= FIBo_AXI_awcache;
		// FIBo_AXI_awprot 	<= FIBo_AXI_awprot;
		// FIBo_AXI_awqos 		<= FIBo_AXI_awqos;
		// FIBo_AXI_awregion 	<= FIBo_AXI_awregion;
		FIBo_AXI_awvalid 	<= FIBo_AXI_awvalid;
		end
	else if(AXI_WA_access) begin
		FIBo_AXI_awid 		<= FIBi_ID;
		FIBo_AXI_awaddr 	<= FIBi_ADDR;
		FIBo_AXI_awlen 		<= FIBo_AXI_axlen_tem;
		FIBo_AXI_awsize 	<= FIBi_BURST;
		FIBo_AXI_awburst 	<= FIBo_AXI_axburst_tem;
		// FIBo_AXI_awlock 	<= FIBo_AXI_axlock_tem;
		// FIBo_AXI_awcache 	<= AXI_AXCACHE;					
		// FIBo_AXI_awprot 	<= AXI_AXPROT;
		// FIBo_AXI_awqos 		<= AXI_AXQOS;
		// FIBo_AXI_awregion 	<= AXI_AXREGION;
		FIBo_AXI_awvalid 	<= FIBi_V;		
		end
	end
		
//AXI_WAACK 
always@(*) begin
	if(AXI_WA_access & FIBi_V) begin
		if(RSTi) begin 
			if(SFR_ACK) begin
				AXI_WAACK = 1'b0;
				end
			else begin
				AXI_WAACK = 1'b1;
				end
			end
		else if(FIBo_AXI_awvalid & !FIBi_AXI_awready) begin
			AXI_WAACK = 1'b0;
			end
		else begin
			if(SFR_ACK) begin
				AXI_WAACK = 1'b0;
				end
			else begin
				AXI_WAACK = 1'b1;
				end
			end
		end
	else begin
		AXI_WAACK = 1'b0;
		end
	end

//--------------------写数据通道----------------------------	
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIBo_AXI_wdata 		<= 'd0;
		FIBo_AXI_wstrb 		<= 'd0;
		FIBo_AXI_wlast 		<= 'd0;
		FIBo_AXI_wvalid    	<= 'd0;
		end
	else if(FIBo_AXI_wvalid & !FIBi_AXI_wready) begin
		FIBo_AXI_wdata 		<= FIBo_AXI_wdata;
		FIBo_AXI_wstrb 		<= FIBo_AXI_wstrb;
		FIBo_AXI_wlast 		<= FIBo_AXI_wlast;
		FIBo_AXI_wvalid    	<= FIBo_AXI_wvalid;
		end
	else if(AXI_WD_access) begin
		FIBo_AXI_wdata 		<= FIBi_DATA;
		FIBo_AXI_wstrb 		<= AXI_WSTRB;
		FIBo_AXI_wlast 		<= op_SEQE;
		FIBo_AXI_wvalid    	<= FIBi_V;
		end
	end

//AXI_WDACK 
always@(*) begin
	if(AXI_WD_access & FIBi_V) begin
		if(RSTi) begin
			if(SFR_ACK) begin
				AXI_WDACK = 1'b0;
				end
			else begin
				AXI_WDACK = 1'b1;
				end
			end
		else if(FIBo_AXI_wvalid & !FIBi_AXI_wready) begin
			AXI_WDACK = 1'b0;
			end
		else begin
			if(SFR_ACK) begin
				AXI_WDACK = 1'b0;
				end
			else begin
				AXI_WDACK = 1'b1;
				end
			end
		end
	else begin
		AXI_WDACK = 1'b0;
		end
	end

//------------------------写回复通道--------------------------------

//AXI_BRPL
always@(*) begin
	if(FIB_state == AMOW) begin
		if(FIBi_AXI_bresp == 2'b01) begin	//EXOKAY
			AXI_BRPL = 8'h10;
			end
		else begin
			AXI_BRPL = 8'hF0;
			end
		end
	else begin
		if(FIBi_AXI_bresp == 2'b00) begin	//OKAY
			AXI_BRPL = 8'h10;
			end
		else begin
			AXI_BRPL = 8'hF0;
			end
		end
	end

//AXI_BID
assign AXI_BID = FIBi_AXI_bid;

//FIBo_AXI_bready
always@(*) begin
	if(FIBi_AXI_bvalid) begin
		if(RSTi) begin
			if(SFR_busying) begin
				FIBo_AXI_bready = 1'b0;
				end
			else begin
				FIBo_AXI_bready = 1'b1;
				end
			end
		else if(FIBo_WREN & FIBi_FULL) begin
			FIBo_AXI_bready = 1'b0;
			end
		else begin
			if(SFR_busying) begin
				FIBo_AXI_bready = 1'b0;
				end
			else begin
				FIBo_AXI_bready = 1'b1;
				end
			end
		end
	else begin
		FIBo_AXI_bready = 1'b0;
		end
	end

//---------------------读地址通道----------------
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIBo_AXI_arid 		<= 'd0;
		FIBo_AXI_araddr 	<= 'd0;
		FIBo_AXI_arlen 		<= 'd0;
		FIBo_AXI_arsize 	<= 'd0;
		FIBo_AXI_arburst 	<= 'd0;
		// FIBo_AXI_arlock 	<= 'd0;
		// FIBo_AXI_arcache 	<= 'd0;
		// FIBo_AXI_arprot 	<= 'd0;
		// FIBo_AXI_arqos 		<= 'd0;
		// FIBo_AXI_arregion 	<= 'd0;
		FIBo_AXI_arvalid 	<= 'd0;
		end
	else if(FIBo_AXI_arvalid & !FIBi_AXI_arready) begin
		FIBo_AXI_arid 		<= FIBo_AXI_arid;
		FIBo_AXI_araddr 	<= FIBo_AXI_araddr;
		FIBo_AXI_arlen 		<= FIBo_AXI_arlen;
		FIBo_AXI_arsize 	<= FIBo_AXI_arsize;
		FIBo_AXI_arburst 	<= FIBo_AXI_arburst;
		// FIBo_AXI_arlock		<= FIBo_AXI_arlock;
		// FIBo_AXI_arcache 	<= FIBo_AXI_arcache;
		// FIBo_AXI_arprot 	<= FIBo_AXI_arprot;
		// FIBo_AXI_arqos 		<= FIBo_AXI_arqos;
		// FIBo_AXI_arregion 	<= FIBo_AXI_arregion;
		FIBo_AXI_arvalid 	<= FIBo_AXI_arvalid;
		end
	else if(AXI_RA_access) begin
		FIBo_AXI_arid 		<= FIBi_ID;
		FIBo_AXI_araddr 	<= FIBi_ADDR;
		FIBo_AXI_arlen 		<= FIBo_AXI_axlen_tem;
		FIBo_AXI_arsize 	<= FIBi_BURST;
		FIBo_AXI_arburst 	<= FIBo_AXI_axburst_tem;
		// FIBo_AXI_arlock 	<= FIBo_AXI_axlock_tem;
		// FIBo_AXI_arcache 	<= AXI_AXCACHE;					
		// FIBo_AXI_arprot 	<= AXI_AXPROT;
		// FIBo_AXI_arqos 		<= AXI_AXQOS;
		// FIBo_AXI_arregion 	<= AXI_AXREGION;
		FIBo_AXI_arvalid 	<= FIBi_V;		
		end
	end

//AXI_RAACK
always@(*) begin
	if(AXI_RA_access & FIBi_V) begin
		if(RSTi) begin
			if(SFR_ACK) begin
				AXI_RAACK = 1'b0;
				end
			else begin
				AXI_RAACK = 1'b1;
				end
			end
		else if(FIBo_AXI_arvalid & !FIBi_AXI_arready) begin
			AXI_RAACK = 1'b0;
			end
		else begin
			if(SFR_ACK) begin
				AXI_RAACK = 1'b0;
				end
			else begin
				AXI_RAACK = 1'b1;
				end
			end
		end
	else begin
		AXI_RAACK = 1'b0;
		end
	end

//----------------------读数据通道-------------------------

//AXI_RID
assign AXI_RID = FIBi_AXI_rid;
//AXI_RD_data
assign AXI_RD_data = FIBi_AXI_rdata;

//AXI_RRPL
always@(*) begin
	if(FIB_state == AMOR) begin
		if(FIBi_AXI_bresp == 2'b01) begin	//EXOKAY
			AXI_RRPL = 8'h10;
			end
		else begin
			AXI_RRPL = 8'hF0;
			end
		end
	else begin
		if(FIBi_AXI_bresp == 2'b00) begin	//OKAY
			if(FIBi_AXI_rlast) begin		
				AXI_RRPL = 8'h10;
				end
			else begin
				AXI_RRPL = 8'h14;
				end
			end
		else begin
			AXI_RRPL = 8'hF0;
			end
		end
	end

//FIBo_AXI_rready
always@(*) begin
	if(FIBi_AXI_rvalid) begin
		if(RSTi) begin
			if(SFR_busying | FIBo_AXI_bready) begin
				FIBo_AXI_rready = 1'b0;
				end
			else begin
				FIBo_AXI_rready = 1'b1;
				end
			end
		else if(FIBo_WREN & FIBi_FULL) begin
			FIBo_AXI_rready = 1'b0;
			end
		else begin
			if(SFR_busying | FIBo_AXI_bready) begin
				FIBo_AXI_rready = 1'b0;
				end
			else begin
				FIBo_AXI_rready = 1'b1;
				end
			end
		end
	else begin
		FIBo_AXI_rready = 1'b0;
		end
	end




endmodule